package com.dgl.sdk.view.autoFitWidthImageView;

import java.io.File;
import java.util.Observable;
import java.util.Observer;

import android.app.ProgressDialog;
import com.dgl.sdk.util.FileDownloader;
import net.tsz.afinal.FinalHttp;
import net.tsz.afinal.http.AjaxCallBack;
import net.tsz.afinal.http.HttpHandler;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import com.dgl.sdk.util.FileCache;

public class ImageZoomView extends View implements Observer {

    private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
    private final Rect mRectSrc = new Rect();
    private final Rect mRectDst = new Rect();
    private float mAspectQuotient;

    private Bitmap mBitmap;
    private ZoomState mState;
    private Context mContext;
    private ZoomState mZoomState;

    public ImageZoomView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mContext = context;
    }

    public void setZoomState(ZoomState state) {
        if (mState != null) {
            mState.deleteObserver(this);
        }
        mState = state;
        mState.addObserver(this);
        invalidate();
    }

    protected void onDraw(Canvas canvas) {
        if (mBitmap != null && mState != null) {
            final int viewWidth = getWidth();
            final int viewHeight = getHeight();
            final int bitmapWidth = mBitmap.getWidth();
            final int bitmapHeight = mBitmap.getHeight();

//            final float zoomX = mState.getZoomX(mAspectQuotient) * viewWidth / bitmapWidth;
//            final float zoomY = mState.getZoomY(mAspectQuotient) * viewHeight / bitmapHeight;

            final float zoomX = mState.getZoom() * viewWidth / bitmapWidth;
            final float zoomY = zoomX;

            if ((mRectSrc.right >= bitmapWidth) && (mRectSrc.left <= 0)) {
                mState.setPanX(0.5f);
            }
            if ((mRectSrc.bottom >= bitmapHeight) && (mRectSrc.top <= 0)) {
                mState.setPanY(0.5f);
            }

            final float panX = mState.getPanX();
            final float panY = mState.getPanY();


            // Setup source and destination rectangles
            mRectSrc.left = (int) (panX * bitmapWidth - viewWidth / (zoomX * 2));
            mRectSrc.top = (int) (panY * bitmapHeight - viewHeight / (zoomY * 2));
            mRectSrc.right = (int) (mRectSrc.left + viewWidth / zoomX);
            mRectSrc.bottom = (int) (mRectSrc.top + viewHeight / zoomY);
            mRectDst.left = getLeft();
            mRectDst.top = getTop();
            mRectDst.right = getRight();
            mRectDst.bottom = getBottom();

            // Adjust source rectangle so that it fits within the source image.
            if (mRectSrc.left < 0) {
                mRectDst.left += -mRectSrc.left * zoomX;
                mRectSrc.left = 0;
            }
            if (mRectSrc.right > bitmapWidth) {
                mRectDst.right -= (mRectSrc.right - bitmapWidth) * zoomX;
                mRectSrc.right = bitmapWidth;
            }
            if (mRectSrc.top < 0) {
                mRectDst.top += -mRectSrc.top * zoomY;
                mRectSrc.top = 0;
            }
            if (mRectSrc.bottom > bitmapHeight) {
                mRectDst.bottom -= (mRectSrc.bottom - bitmapHeight) * zoomY;
                mRectSrc.bottom = bitmapHeight;
            }

            if ((mRectDst.left > 0) && (mRectDst.right == viewWidth)) {
                mRectDst.left = 0;
                mRectSrc.right = (int) (viewWidth / zoomX);
                float offsetX = (viewWidth / (zoomX * 2)) / bitmapWidth;
                mState.setPanX(offsetX);
            }

            if ((mRectDst.right < viewWidth) && (mRectDst.left == 0)) {
                mRectDst.right = viewWidth;
                mRectSrc.left = bitmapWidth - (int) (viewWidth / zoomX);

                float offsetX = 1 - (viewWidth / (zoomX * 2 * bitmapWidth));
                mState.setPanX(offsetX);
            }

            if ((mRectDst.top > 0) && (mRectDst.bottom == viewHeight)) {
                mRectDst.top = 0;
                mRectSrc.bottom = (int) (viewHeight / zoomY);
                float offsetY = (viewHeight / (zoomY * 2)) / bitmapHeight;
                mState.setPanY(offsetY);
            }

            if ((mRectDst.bottom < viewHeight) && (mRectDst.top == 0)) {
                mRectDst.bottom = viewHeight;
                mRectSrc.top = bitmapHeight - (int) (viewHeight / zoomY);

                float offsetY = 1 - (viewHeight / (zoomY * 2 * bitmapHeight));
                mState.setPanY(offsetY);
            }

            canvas.drawBitmap(mBitmap, mRectSrc, mRectDst, mPaint);
        }
    }

    public float getImgWidth() {
        return mState.getZoomX(mAspectQuotient) * mBitmap.getWidth();
    }

    public float getImgHeight() {
        return mBitmap.getHeight();
    }


    public void update(Observable observable, Object data) {
        invalidate();
    }

    private void calculateAspectQuotient() {
        if (mBitmap != null) {
            mAspectQuotient =
                    (((float) mBitmap.getWidth()) / mBitmap.getHeight()) /
                            (((float) getWidth()) / getHeight());
        }
    }

    private void setImageBitmap(Bitmap bitmap) {
        mBitmap = bitmap;
        calculateAspectQuotient();
        invalidate();

        initToShow();
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        calculateAspectQuotient();
    }


    private void initToShow() {
//        this.setImage(mBitmap);
        mZoomState = new ZoomState();
        this.setZoomState(mZoomState);
        SimpleZoomListener zoomListener = new SimpleZoomListener();
        zoomListener.setZoomState(mZoomState);
        this.setOnTouchListener(zoomListener);
        resetZoomState();

    }

    /**
     *
     * @param file 图片文件
     */
    public void show(File file){
        setImageBitmap(BitmapFactory.decodeFile(file.getAbsolutePath()));
    }
    /**
     *
     * @param imgurl
     * @param cacheDir 缓存地址  保存在本地  用filecache 来管理
     */
    public void show(final String imgurl, final String cacheDir){
        show(imgurl, cacheDir, false);
    }

    /**
     *
     * @param imgurl
     * @param cacheDir  缓存地址  保存在本地  用filecache 来管理
     */
    public void show(final String imgurl, final String cacheDir, final boolean showProgress) {

       final ProgressDialog progressDialog = new ProgressDialog(mContext);

        if(showProgress){

            progressDialog.setMessage("正在加载");
            progressDialog.show();
        }


    	FileCache fileCache = new FileCache(mContext, cacheDir);

        File imagFile = fileCache.getFromFileCache(imgurl);
        if(imagFile.exists()){
            setImageBitmap(BitmapFactory.decodeFile(imagFile.getAbsolutePath()));

            if(showProgress){
                progressDialog.dismiss();
            }

        }else{
            FileDownloader fd = new FileDownloader(mContext, imgurl,
                    fileCache.getFileCacheDir(), imagFile.getName(), 1, new FileDownloader.DownloadCallback() {
                @Override
                public void onStart() {

                }

                @Override
                public void onProgress(int progress) {
                    if (showProgress) {
                        progressDialog.setMessage("正在加载" + progress + "%");
                    }
                }

                @Override
                public void onComplete(String filePath) {
                    setImageBitmap(BitmapFactory.decodeFile(filePath));
                    if (showProgress) {
                        progressDialog.dismiss();
                    }
                }

                @Override
                public void onError(String error) {
                    progressDialog.dismiss();
                }
            });

            fd.download();
        }
//            FinalHttp fh = new FinalHttp();
//            HttpHandler handler = fh.download(imgurl, imagFile.getAbsolutePath(), new AjaxCallBack<File>() {
//
//                @Override
//                public void onFailure(Throwable t, int errorNo, String strMsg) {
//                    super.onFailure(t, errorNo, strMsg);
//                    progressDialog.dismiss();
//                }
//
//                @Override
//                public void onFailure(Throwable t, String strMsg) {
//                    super.onFailure(t, strMsg);
//                    progressDialog.dismiss();
//                }
//
//                @Override
//                public void onLoading(long count, long current) {
//                    super.onLoading(count, current);
//                    if(showProgress){
//                        progressDialog.setMessage("正在加载"+ (Long.toString((current*100/count))) + "%");
//                    }
//
//                }
//
//                @Override
//                public void onSuccess(File t) {
//                    super.onSuccess(t);
//                    setImageBitmap(BitmapFactory.decodeFile(t.getAbsolutePath()));
//                    if(showProgress){
//                        progressDialog.dismiss();
//                    }
//                }
//
//            }.progress(true, 500)); //显示进度， 500 毫秒更新一次
//        }
    	

//        new Thread(){
//            @Override
//            public void run() {
//                super.run();
//                FileCache fileCache = new FileCache(mContext, cacheDir);
//
//                FileDownloader fd = new FileDownloader(mContext);
//                try {
//                    fd.download(imgurl, fileCache.GetImageFileDir(), fileCache.urlToFileName(imgurl), 1, new FileDownloader.DownloadCallback() {
//                        @Override
//                        public void onStart() {
//
//                        }
//
//                        @Override
//                        public void onProgress(int progress) {
//
//                        }
//
//                        @Override
//                        public void onComplete(String filePath) {
//                            mBitmap = BitmapFactory.decodeFile(filePath);
//                            initToShow();
//                        }
//
//                        @Override
//                        public void onError(String error) {
//
//                        }
//                    });
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }.start();



    }

    private void resetZoomState() {
        mZoomState.setPanX(0.5f);
        mZoomState.setZoom(1f);
        if ((((float) this.getWidth() / (float) mBitmap.getWidth()) * mBitmap
                .getHeight()) > this.getHeight()) {
            float offsetY = ((float) this.getHeight() / ((float) (this
                    .getWidth() / (float) mBitmap.getWidth()) * 2))
                    / (float) mBitmap.getHeight();
            mZoomState.setPanY(offsetY);
        } else {
            mZoomState.setPanY(0.5f);
        }

        mZoomState.notifyObservers();
    }

}